using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Krilib.Bridges;

namespace Krile.Subsystem
{
    /// <summary>
    /// Debugging Agent
    /// </summary>
    internal static class Debugger
    {
        private static List<DebugReport> reports = new List<DebugReport>();

        internal static void AddReport(DebugReport rep)
        {
            if (Core.Config != null && Core.Config.Security.Ignores != null)
            {
                foreach (var i in Core.Config.Security.Ignores)
                {
                    if (i.IsIgnoreReport(rep))
                        return;
                }
            }
            reports.Add(rep);
            if (Core.FormManager != null && Core.FormManager.MainForm != null)
                Core.FormManager.MainForm.UpdateInfobar();
        }

        internal static void AddReport(Exception excp)
        {
            AddReport(new DebugReport(excp));
        }

        internal static void AddReport(string msg)
        {
            AddReport(new DebugReport(msg));
        }

        internal static void Assert(bool expression,string message)
        {
            if (!expression)
                throw new KrileStrictCheckException(message);
        }

        internal static void WriteReport(bool onlyDisaster)
        {
            StringBuilder writeStr = new StringBuilder();
            foreach (var rp in reports)
            {
                if (onlyDisaster && rp.Priority != DebugReport.Priorities.Fatal)
                    continue;
                writeStr.AppendLine("> " + rp.DateTime + " - PR:"+ rp.Priority.ToString());
                writeStr.AppendLine(" MSG:" + rp.Message);
                if (rp.IsExceptionReport)
                {
                    writeStr.AppendLine(" @Exception Report---");
                    writeStr.AppendLine(rp.Exception.ToString());
                }
                writeStr.AppendLine();
            }
            if (writeStr.ToString() != "")
            {
                using (StreamWriter sw = new StreamWriter(Path.Combine(Define.AppPath, Define.DebugReportFileName), true))
                {
                    sw.WriteLine(writeStr.ToString());
                }
            }
        }

        internal static void ClearReports()
        {
            reports.Clear();
            if (Core.FormManager != null && Core.FormManager.MainForm != null)
                Core.FormManager.MainForm.UpdateInfobar();
        }

        internal static DebugReport[] GetReports()
        {
            var ret = reports.ToArray();
            reports.Clear();
            if (Core.FormManager != null && Core.FormManager.MainForm != null)
                Core.FormManager.MainForm.UpdateInfobar();
            return ret;
        }

        internal static void SetReports(DebugReport[] reps)
        {
            reports.Clear();
            if (reps != null)
                reports.AddRange(reps);
            if (Core.FormManager != null && Core.FormManager.MainForm != null)
                Core.FormManager.MainForm.UpdateInfobar();
        }

        internal static int GetReportLength()
        {
            return reports.Count;
        }
    }

    public class __DebugBridge : IDebugReporter
    {
        public void AddReport(DebugReport report)
        {
            Debugger.AddReport(report);
        }

        public void AddReport(Exception excp)
        {
            Debugger.AddReport(excp);
        }

        public void AddReport(string reportstr)
        {
            Debugger.AddReport(reportstr);
        }
    }
}
